package com.ruoyi.system.util;

import com.ruoyi.common.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;

import javax.net.ssl.HttpsURLConnection;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.net.URL;
import java.nio.charset.StandardCharsets;

/**
 * 自定义微信支付工具类
 *
 * @author dida
 */
@Slf4j
public class WxChatPayCommonUtil {
    /**
     * 发送 http 请求
     *
     * @param requestUrl    请求路径
     * @param requestMethod 请求方式(GET/POST/PUT/DELETE/...)
     * @param outputStr     请求参数体
     * @return 结果信息
     */
    public static String httpsRequest(String requestUrl, String requestMethod, String outputStr) {
        try {
            URL url = new URL(requestUrl);
            HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setUseCaches(false);
            // 设置请求方式（GET/POST）
            conn.setRequestMethod(requestMethod);
            conn.setRequestProperty("content-type", "application/xml");
            // 当outputStr不为null时向输出流写数据
            if (null != outputStr) {
                OutputStream outputStream = conn.getOutputStream();
                // 注意编码格式
                outputStream.write(outputStr.getBytes(StandardCharsets.UTF_8));
                outputStream.close();
            }
            // 从输入流读取返回内容
            InputStream inputStream = conn.getInputStream();
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
            String str = null;
            StringBuffer buffer = new StringBuffer();
            while ((str = bufferedReader.readLine()) != null) {
                buffer.append(str);
            }
            // 释放资源
            bufferedReader.close();
            inputStreamReader.close();
            inputStream.close();
            inputStream = null;
            conn.disconnect();
            return buffer.toString();
        } catch (Exception e) {
            log.error("https请求失败：{}", e.getMessage());
        }
        return null;
    }

    /**
     * 获取客户端真实IP地址
     *
     * @param request HTTP请求对象
     * @return 处理后的IP地址
     */
    public static String getIp(HttpServletRequest request) {
        if (request == null) {
            return "";
        }

        String[] headers = {
                "X-Requested-For",
                "X-Forwarded-For",
                "Proxy-Client-IP",
                "WL-Proxy-Client-IP",
                "HTTP_CLIENT_IP",
                "HTTP_X_FORWARDED_FOR"
        };

        String ip = "";
        for (String header : headers) {
            ip = request.getHeader(header);
            if (isValidIp(ip)) {
                break;
            }
        }

        if (!isValidIp(ip)) {
            ip = request.getRemoteAddr();
        }

        // 处理X-Forwarded-For多IP情况
        if (ip != null && ip.contains(",")) {
            ip = ip.split(",")[0].trim();
        }

        // 处理IPv6本地地址
        if ("0:0:0:0:0:0:0:1".equals(ip)) {
            ip = "127.0.0.1";
        }

        return ip == null ? "" : ip;
    }

    /**
     * 验证给定的IP地址是否有效。
     *
     * @param ip 要验证的IP地址字符串
     * @return 如果IP地址有效，则返回true；否则返回false
     */
    private static boolean isValidIp(String ip) {
        if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
            return false;
        }

        String ipPattern = "^((25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)$";
        return ip.matches(ipPattern);
    }



    /**
     * 从流中读取微信返回的xml数据
     *
     * @param httpServletRequest 请求对象，包含微信服务器发送过来的xml数据
     * @return 从流中读取到的xml数据字符串
     * @throws IOException 如果在读取流的过程中发生IO异常，将抛出此异常
     */
    public static String readXmlFromStream(HttpServletRequest httpServletRequest) throws IOException {
        InputStream inputStream = httpServletRequest.getInputStream();
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
        final StringBuffer sb = new StringBuffer();
        String line = null;
        try {
            while ((line = bufferedReader.readLine()) != null) {
                sb.append(line);
            }
        } finally {
            bufferedReader.close();
            inputStream.close();
        }

        return sb.toString();
    }

    /**
     * 设置返回给微信服务器的xml信息
     *
     * @param returnCode 返回码，表示消息的处理结果
     * @param returnMsg 返回消息，对返回码的文本描述
     * @return 格式化后的xml字符串，包含returnCode和returnMsg信息
     */
    public static String setReturnXml(String returnCode, String returnMsg) {
        return "<xml><return_code><![CDATA[" + returnCode + "]]></return_code><return_msg><![CDATA[" + returnMsg + "]]></return_msg></xml>";
    }
}
